/*

Miranda IM: the free IM client for Microsoft* Windows*

Copyright 2000-2007 Miranda ICQ/IM project, 
all portions of this codebase are copyrighted to the people 
listed in contributors.txt.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
#include "commonheaders.h"
#include "ExtraServices.h"
#include "m_contacts.h"

INT GetContactInfo(WPARAM wParam, LPARAM lParam);

namespace NServices {
namespace NGender {

static HANDLE nhExtraIconF	= INVALID_HANDLE_VALUE;
static HANDLE nhExtraIconM	= INVALID_HANDLE_VALUE;

BYTE DBGetContactGender(HANDLE hContact)
{
	CONTACTINFO ci;

	ci.cbSize = sizeof(CONTACTINFO);
	ci.hContact = hContact;
	ci.szProto = NULL;
	ci.dwFlag = CNF_GENDER;
	ci.bVal = 0;

	if(GetContactInfo(NULL, (LPARAM)&ci))
		return 0;
	return ci.bVal;
}

/***********************************************************************************************************
 * Event Handler functions
 ***********************************************************************************************************/

static INT OnCListRebuildIcons(WPARAM wParam, LPARAM lParam)
{
	nhExtraIconF = (HANDLE)CallService(MS_CLIST_EXTRA_ADD_ICON, (WPARAM)NIcoLib::GetIcon(ICO_COMMON_FEMALE), 0);;
	nhExtraIconM = (HANDLE)CallService(MS_CLIST_EXTRA_ADD_ICON, (WPARAM)NIcoLib::GetIcon(ICO_COMMON_MALE), 0);;
	return 0;
}

/**
 * name:	OnCListApplyIcons
 * desc:	notification handler for clist extra icons to be applied for a contact
 * param:	wParam	- handle to the contact whose extra icon is to apply
 *			lParam	- not used
 **/
static INT OnCListApplyIcons(WPARAM wParam, LPARAM lParam)
{
	IconExtraColumn iec;

	iec.ColumnType = ColumnType(DBGetByte(SET_CLIST_EXTRAICON_GENDER, DEFVAL_CLIST_EXTRAICON_GENDER));
	if(iec.ColumnType) {
		iec.cbSize = sizeof(IconExtraColumn);
		switch(DBGetContactGender((HANDLE)wParam)) {
			case 'M': iec.hImage = nhExtraIconM; break;
			case 'F': iec.hImage = nhExtraIconF; break;
			default:  iec.hImage = INVALID_HANDLE_VALUE;
		}
		CallService(MS_CLIST_EXTRA_SET_ICON, wParam, (LPARAM)&iec);
	}
	return 0;
}

/**
 * name:	OnContactSettingChanged
 * desc:	Notification handler for changed contact settings
 * param:	wParam	-	(HANDLE)hContact
 *			lParam	-	(DBCONTACTWRITESETTING*)pdbcws
 * return:	0 if setting was handled or 1 if not
 **/
static INT OnContactSettingChanged(WPARAM wParam, LPARAM lParam)
{
	DBCONTACTWRITESETTING* pdbcws = (DBCONTACTWRITESETTING*)lParam;
	if(!_stricmp(pdbcws->szSetting, SET_CONTACT_GENDER)) {
		IconExtraColumn iec;

		iec.ColumnType = ColumnType(DBGetByte(SET_CLIST_EXTRAICON_GENDER, DEFVAL_CLIST_EXTRAICON_GENDER));
		if(iec.ColumnType) {
			iec.cbSize = sizeof(IconExtraColumn);
			iec.hImage = INVALID_HANDLE_VALUE;
			if(pdbcws->value.type == DBVT_BYTE) {
				switch(pdbcws->value.bVal) {
					case 'M': iec.hImage = nhExtraIconM; break;
					case 'F': iec.hImage = nhExtraIconF; break;
				}
			}
			CallService(MS_CLIST_EXTRA_SET_ICON, wParam, (LPARAM)&iec);
		}
	}
	return 0;
}

/***********************************************************************************************************
 * public Module Interface functions
 ***********************************************************************************************************/

/**
 * name:	ApplyCListIcons
 * desc:	force all icons to be reloaded
 * param:	wParam	- handle to the contact whose extra icon is to apply
 *			lParam	- not used
 **/
VOID ApplyCListIcons()
{
	WPARAM wContact;

	//walk through all the contacts stored in the DB
	for(wContact = CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
		wContact != NULL;
		wContact = CallService(MS_DB_CONTACT_FINDNEXT, wContact, 0))
	{
		OnCListApplyIcons(wContact, 0);
	}
}

/**
 * name:	EnableExtraIcons
 * desc:	reload the module
 * params:	bEnable	- determines whether icons are enabled or not
 * return:	0
 **/
VOID EnableExtraIcons(BOOLEAN bEnable) 
{
	static HANDLE	hChangedHook = 0,
					hApplyIconHook = 0,
					hRebuildIconsHook = 0;

	if(!myGlobals.HaveCListExtraIcons)
		return;

	if(bEnable) {
		// hook events
		if(hChangedHook == NULL) hChangedHook = HookEvent(ME_DB_CONTACT_SETTINGCHANGED, OnContactSettingChanged);
		if(hApplyIconHook == NULL) hApplyIconHook = HookEvent(ME_CLIST_EXTRA_IMAGE_APPLY, OnCListApplyIcons);
		if(hRebuildIconsHook == NULL) hRebuildIconsHook = HookEvent(ME_CLIST_EXTRA_LIST_REBUILD, OnCListRebuildIcons);

		OnCListRebuildIcons(0, 0);
	}
	else {
		UnhookEvent(hChangedHook); hChangedHook = NULL;
		UnhookEvent(hApplyIconHook); hApplyIconHook = NULL;
		UnhookEvent(hRebuildIconsHook); hRebuildIconsHook = NULL;
	}
	ApplyCListIcons();
}

/**
 * name:	OnModulesLoaded
 * desc:	initialize stuff, which require all standard modules to bee loaded
 * params:	none
 * return:	0
 **/
VOID OnModulesLoaded()
{
	EnableExtraIcons(DBGetByte(SET_CLIST_EXTRAICON_GENDER, DEFVAL_CLIST_EXTRAICON_GENDER));
}

} /* namespace NGender */
} /* namespace NServices */
